package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.jetcache.utils.JetCacheUtils;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.common.vo.dict.DictQueryVO;
import com.bifang.module.base.common.vo.dict.DictVO;
import com.bifang.module.base.common.vo.operationPeriod.OperationCurVO;
import com.bifang.module.base.common.vo.operationPeriod.OperationPeriodQueryVO;
import com.bifang.module.base.common.vo.operationPeriod.OperationPeriodVO;
import com.bifang.module.base.core.helper.DictHelper;
import com.bifang.module.base.core.integration.CommonIntegration;
import com.bifang.module.system.common.enums.OperatingPeriodDictEnum;
import com.bifang.module.system.core.dao.model.OperationPeriod;
import com.bifang.module.system.core.dao.model.SysDict;
import com.bifang.module.system.core.dao.model.SysOrg;
import com.bifang.module.system.core.dao.service.OperationPeriodService;
import com.bifang.module.system.core.dao.service.SysDictService;
import com.bifang.module.system.core.dao.service.SysOrgService;
import com.bifang.module.system.core.integration.impl.DictIntegrationImpl;
import com.bifang.module.system.core.integration.impl.OperationPeriodIntegrationImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.constant.EduCache;
import com.jwsoft.manager.common.vo.cache.EduOperationCacheDetailVO;
import com.jwsoft.manager.common.vo.cache.EduOperationCacheQueryVO;
import com.jwsoft.manager.common.vo.cache.EduOperationCacheVO;
import com.jwsoft.manager.core.integration.OperationCacheIntegration;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 行政区划表业务实现类
 *
 * @author hhj
 * @since 2022-12-28
 */
@ApiService(funcCode = "OperationCache", title = "教育业务期控制参数管理")
public class OperationCacheIntegrationImpl implements OperationCacheIntegration {

    @Resource
    public OperationPeriodIntegrationImpl operationPeriodIntegration;

    @Autowired
    public OperationPeriodService operationPeriodService;

    @Autowired
    public CommonIntegration commonIntegration;

    @Autowired
    public SysDictService sysDictService;

    @Autowired
    private SysOrgService sysOrgService;

    @Autowired
    private DictHelper dictHelper;

    @Autowired
    private DictIntegrationImpl dictIntegration;

    private static final Pattern pattern = Pattern.compile("\\$\\{(\\s*)([\\S]+?)(\\s*)\\}");

    @Override
    @OpApi(funcCode = "OperationCache0001", title = "获取招生时间控制参数 ", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE,savelog = false)
    @Cached(name = EduCache.OPERATION_PERIOD_EDU, key = "#vo.keyTime", cacheType = CacheType.BOTH, expire = 86400, localExpire = 20)
    public EduOperationCacheVO getEduOperation(EduOperationCacheQueryVO vo) {
        Integer year=vo.getYear();
        if(year==null){
            OperationCurVO curVO = new OperationCurVO();
            curVO.setOperating("XN");
            OperationPeriodVO periodVO = operationPeriodIntegration.getCurrentByOperating(curVO);
            if (periodVO != null) {
                year = periodVO.getPeriodYear();
            } else {
                year = DateUtil.thisYear();
            }
        }
        String areaCode=vo.getAreaCode();
        if(StringUtils.isBlank(areaCode)){
            areaCode= SessionUtil.getAreaCode();
        }
        if(StringUtils.isBlank(areaCode)){
            throw new AppException("行政区划不能为空");
        }
        EduOperationCacheVO cacheVO = new EduOperationCacheVO();

        List<SysDict> sysDictList = new ArrayList<>();
                QueryWrapper<SysDict> dictVOQueryWrapper = new QueryWrapper<>();
        dictVOQueryWrapper.lambda().eq(SysDict::getDictField,"OPERATING")
                                    .eq(SysDict::getAreaCode,areaCode)
                                    .eq(SysDict::getClassify,vo.getClassify());
        sysDictList = sysDictService.list(dictVOQueryWrapper);
        if (CollectionUtils.isEmpty(sysDictList)){
            SysOrg sysOrg = sysOrgService.getById(areaCode);
            if (ObjectUtils.isNotEmpty(sysOrg)){
                dictVOQueryWrapper.clear();
                dictVOQueryWrapper.lambda().eq(SysDict::getDictField,"OPERATING")
                        .eq(SysDict::getAreaCode,sysOrg.getParentId())
                        .eq(SysDict::getClassify,vo.getClassify());
                sysDictList = sysDictService.list(dictVOQueryWrapper);
            }
        }
        List<DictVO> dictVOList = Convert.toList(DictVO.class,sysDictList);
        cacheVO.setYear(year);
        List<String> dictKeyList = dictVOList.stream().map(DictVO::getDictKey).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(dictKeyList)){
            cacheVO.setOperation(new HashMap<>());
            return cacheVO;
        }
        QueryWrapper<OperationPeriod> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .in(OperationPeriod::getOperating, dictKeyList)
                .eq(OperationPeriod::getPeriodYear,year)
                .eq(OperationPeriod::getAreaCode,areaCode);
        List<OperationPeriod> list=operationPeriodService.list(queryWrapper);
        Map<String, EduOperationCacheDetailVO> operation = new HashMap<>();
        for(OperationPeriod operationPeriod:list){
            EduOperationCacheDetailVO eduOperationCacheDetailVO = new EduOperationCacheDetailVO();
            eduOperationCacheDetailVO.setBegTime(operationPeriod.getBegTime());
            eduOperationCacheDetailVO.setYear(operationPeriod.getPeriodYear());
            eduOperationCacheDetailVO.setEndTime(operationPeriod.getEndTime());
            eduOperationCacheDetailVO.setOperating(operationPeriod.getOperating());
            if(StringUtils.isBlank(operationPeriod.getMessagePrompts())){
                operationPeriod.setMessagePrompts("业务操作期未开始");
            }else{
                String messagePrompts = operationPeriod.getMessagePrompts();
                StringBuffer sb = new StringBuffer(messagePrompts);
                Matcher matcher = pattern.matcher(messagePrompts);
                int offset = 0;
                while (matcher.find()) {
                    String varName = matcher.group(2);
                    String replaceStr="";
                    if("year".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getPeriodYear())){
                            replaceStr=operationPeriod.getPeriodYear().toString();
                        }
                    }
                    if("ym".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getYm())){
                            replaceStr=operationPeriod.getYm().toString();
                        }
                    }
                    if("begTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getBegTime())){
                            replaceStr=DateUtil.format(operationPeriod.getBegTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    if("endTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getEndTime())){
                            replaceStr=DateUtil.format(operationPeriod.getEndTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    sb.replace(matcher.start() + offset, matcher.end() + offset, replaceStr);

                    offset += replaceStr.length() - matcher.group().length();
                }
                eduOperationCacheDetailVO.setMessagePrompts(sb.toString());
            }
            if(StringUtils.isBlank(operationPeriod.getMessageTip())){
                operationPeriod.setMessageTip("业务操作期已结束");
            }else{
                String messageTip = operationPeriod.getMessageTip();
                StringBuffer sb = new StringBuffer(messageTip);
                Matcher matcher = pattern.matcher(messageTip);
                int offset = 0;
                while (matcher.find()) {
                    String varName = matcher.group(2);
                    String replaceStr="";
                    if("year".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getPeriodYear())){
                            replaceStr=operationPeriod.getPeriodYear().toString();
                        }
                    }
                    if("ym".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getYm())){
                            replaceStr=operationPeriod.getYm().toString();
                        }
                    }
                    if("begTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getBegTime())){
                            replaceStr=DateUtil.format(operationPeriod.getBegTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    if("endTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getEndTime())){
                            replaceStr=DateUtil.format(operationPeriod.getEndTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    sb.replace(matcher.start() + offset, matcher.end() + offset, replaceStr);

                    offset += replaceStr.length() - matcher.group().length();
                }
                eduOperationCacheDetailVO.setMessageTip(sb.toString());
            }


            operation.put(operationPeriod.getOperating(),eduOperationCacheDetailVO);
        }
        //未查到数据 该业务没有维护
        for(String key:dictKeyList){
            EduOperationCacheDetailVO eduOperationCacheDetailVO = new EduOperationCacheDetailVO();
            if(!operation.containsKey(key)){
                eduOperationCacheDetailVO.setOperating(key);
                eduOperationCacheDetailVO.setFlag(false);
                eduOperationCacheDetailVO.setType("3");
                eduOperationCacheDetailVO.setYear(year);
                operation.put(key,eduOperationCacheDetailVO);
            }
        }
        cacheVO.setOperation(operation);


        return cacheVO;

    }

    @Override
    @OpApi(funcCode = "OperationCache0002", title = "操作期清除缓存", funcType = FuncTypeEnum.other)
    public void clearCache(EduOperationCacheQueryVO vo) {
        if(StringUtils.isBlank(vo.getClassify())){
            throw new AppException("请传入查询的是义务段还是幼儿园");
        }
        if(StringUtils.isBlank(vo.getAreaCode())){
            vo.setAreaCode(SessionUtil.getAreaCode());
        }
        if(StringUtils.isBlank(vo.getAreaCode())){
            throw new AppException("请传入查询的行政区划");
        }
        vo.setKeyTime(vo.getClassify()+":"+vo.getAreaCode()+":"+DateUtil.format(new Date(),"yyyyMMdd"));
        this.clearCache(vo.getKeyTime());
    }

    private void clearCache(String keyTime) {
        if (StringUtils.isNotBlank(keyTime)) {
            Cache cache = JetCacheUtils.create(EduCache.OPERATION_PERIOD_EDU, CacheType.BOTH);
            if (cache != null) {
                cache.remove(keyTime);
            }
        }
    }


    @Override
    @OpApi(funcCode = "OperationCache0005", title = "获取招生年度参数 ", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE,savelog = false)
    public EduOperationCacheDetailVO getPeriodYear(OperationCurVO vo) {
        OperationCurVO curVO = new OperationCurVO();
        curVO.setOperating("XN");
        curVO.setAreaCode(vo.getAreaCode());
        //倒序获取数据里最后一年的数据
        List<OperationPeriodVO> list=operationPeriodIntegration.getListByOperatingLastYear(curVO);
        EduOperationCacheDetailVO eduOperationCacheDetailVO = new EduOperationCacheDetailVO();
        if(!CollectionUtils.isEmpty(list)){
            OperationPeriodVO operationPeriod = list.get(0);

            eduOperationCacheDetailVO.setBegTime(operationPeriod.getBegTime());
            eduOperationCacheDetailVO.setYear(operationPeriod.getPeriodYear());
            eduOperationCacheDetailVO.setEndTime(operationPeriod.getEndTime());
            Long  begTime =null;
            Long  endTime =null;
            Long  curTime = DateUtil.currentSeconds();
            if(operationPeriod.getBegTime()!=null){
                begTime = operationPeriod.getBegTime().getTime()/1000;
            }
            if(operationPeriod.getEndTime()!=null){
                endTime = operationPeriod.getEndTime().getTime()/1000;
            }
            if(begTime!=null&&curTime<begTime){
                eduOperationCacheDetailVO.setFlag(false);
                eduOperationCacheDetailVO.setType("1");
            }else if(endTime!=null&&curTime>endTime){
                eduOperationCacheDetailVO.setFlag(false);
                eduOperationCacheDetailVO.setType("2");
            }else{
                eduOperationCacheDetailVO.setFlag(true);
            }
            if(StringUtils.isBlank(operationPeriod.getMessagePrompts())){
                operationPeriod.setMessagePrompts("业务操作期未开始");
            }else{
                String messagePrompts = operationPeriod.getMessagePrompts();
                StringBuffer sb = new StringBuffer(messagePrompts);
                Matcher matcher = pattern.matcher(messagePrompts);
                int offset = 0;
                while (matcher.find()) {
                    String varName = matcher.group(2);
                    String replaceStr="";
                    if("year".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getPeriodYear())){
                            replaceStr=operationPeriod.getPeriodYear().toString();
                        }
                    }
                    if("ym".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getYm())){
                            replaceStr=operationPeriod.getYm().toString();
                        }
                    }
                    if("begTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getBegTime())){
                            replaceStr=DateUtil.format(operationPeriod.getBegTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    if("endTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getEndTime())){
                            replaceStr=DateUtil.format(operationPeriod.getEndTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    sb.replace(matcher.start() + offset, matcher.end() + offset, replaceStr);

                    offset += replaceStr.length() - matcher.group().length();
                }
                eduOperationCacheDetailVO.setMessagePrompts(sb.toString());
            }
            if(StringUtils.isBlank(operationPeriod.getMessageTip())){
                operationPeriod.setMessageTip("业务操作期已结束");
            }else{
                String messageTip = operationPeriod.getMessageTip();
                StringBuffer sb = new StringBuffer(messageTip);
                Matcher matcher = pattern.matcher(messageTip);
                int offset = 0;
                while (matcher.find()) {
                    String varName = matcher.group(2);
                    String replaceStr="";
                    if("year".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getPeriodYear())){
                            replaceStr=operationPeriod.getPeriodYear().toString();
                        }
                    }
                    if("ym".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getYm())){
                            replaceStr=operationPeriod.getYm().toString();
                        }
                    }
                    if("begTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getBegTime())){
                            replaceStr=DateUtil.format(operationPeriod.getBegTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    if("endTime".equals(varName)){
                        if(ObjectUtils.isNotEmpty(operationPeriod.getEndTime())){
                            replaceStr=DateUtil.format(operationPeriod.getEndTime(),"yyyy-MM-dd HH:mm:ss");
                        }
                    }
                    sb.replace(matcher.start() + offset, matcher.end() + offset, replaceStr);

                    offset += replaceStr.length() - matcher.group().length();
                }
                eduOperationCacheDetailVO.setMessageTip(sb.toString());
            }

        }else{
            eduOperationCacheDetailVO.setYear(DateUtil.thisYear());
            eduOperationCacheDetailVO.setFlag(false);
            eduOperationCacheDetailVO.setType("3");
        }
        return eduOperationCacheDetailVO;

    }

    @Override
    public EduOperationCacheDetailVO getPeriodYear() {
        return getPeriodYear(new OperationCurVO());
    }

    @Override
    @OpApi(funcCode = "OperationCache0007", title = "教育业务期管理根据分类分页查询 ", funcType = FuncTypeEnum.query,publicFlag = BoolEnum.TRUE,savelog = false)
    public PageInfo<OperationPeriodVO> getOperationListByClassify(OperationPeriodQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            vo.setPageNum(1);
            vo.setPageSize(50);
        }
        if (ObjectUtils.isEmpty(vo.getPeriodYear())){
            throw new AppException("年份不能为空！");
        }
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        List<SysDict> sysDictList = new ArrayList<>();
        if (ObjectUtils.isEmpty(vo.getAreaCode())){
            vo.setAreaCode(SessionUtil.getAreaCode());
        }
        //查询字典中模板数据
        QueryWrapper<SysDict> dictQueryWrapper = new QueryWrapper<>();
        dictQueryWrapper.lambda()
                .eq(SysDict::getDictField,"OPERATING")
                .eq(!ObjectUtils.isEmpty(vo.getClassify()),SysDict::getClassify,vo.getClassify())
                .eq(!ObjectUtils.isEmpty(vo.getOperating()),SysDict::getDictKey,vo.getOperating())
                .eq(!ObjectUtils.isEmpty(vo.getAreaCode()),SysDict::getAreaCode,vo.getAreaCode())
                .orderByAsc(SysDict::getOrderNo);
        PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
        sysDictList = sysDictService.list(dictQueryWrapper);

        if (CollectionUtils.isEmpty(sysDictList)){
            dictQueryWrapper.clear();
            SysOrg sysOrg = sysOrgService.getById(vo.getAreaCode());
            if (ObjectUtils.isNotEmpty(sysOrg)){
                dictQueryWrapper.lambda()
                        .eq(SysDict::getDictField,"OPERATING")
                        .eq(!ObjectUtils.isEmpty(vo.getClassify()),SysDict::getClassify,vo.getClassify())
                        .eq(!ObjectUtils.isEmpty(vo.getOperating()),SysDict::getDictKey,vo.getOperating())
                        .eq(SysDict::getAreaCode,sysOrg.getParentId())
                        .orderByAsc(SysDict::getOrderNo);
                PageHelper.startPage(vo.getPageNum(),vo.getPageSize());
                sysDictList = sysDictService.list(dictQueryWrapper);
            }
            if (CollectionUtils.isEmpty(sysDictList)){
                return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
            }
        }
        //保留分页信息
        PageInfo<SysDict> pageInfo = new PageInfo<>(sysDictList);
        //去operation_period中查询
        QueryWrapper<OperationPeriod> periodQueryWrapper = new QueryWrapper<>();
        periodQueryWrapper.lambda()
                .eq(OperationPeriod::getAreaCode,vo.getAreaCode())
                .eq(OperationPeriod::getPeriodYear,vo.getPeriodYear())
        ;
        Boolean periodNullFlag = false;
        Map<String, List<OperationPeriod>> operationMap  = new HashMap<>();
        List<OperationPeriod> periodList = operationPeriodService.list(periodQueryWrapper);
        if (CollectionUtils.isEmpty(periodList)){
            periodNullFlag = true;
        }else{
            periodNullFlag = false;
            //如果有数据，就按照操作期编号进行分组
            operationMap = periodList.stream().collect(Collectors.groupingBy(OperationPeriod::getOperating));
        }
        Boolean finalPeriodNullFlag = periodNullFlag;
        Map<String, List<OperationPeriod>> finalOperationMap = operationMap;
        List<OperationPeriodVO> list = sysDictList.stream().map(item -> {
            OperationPeriodVO periodVO = new OperationPeriodVO();
            //如果没有数据，就按照模板中的数据进行填充
            if (finalPeriodNullFlag) {
                periodVO.setOperating(item.getDictKey());
                periodVO.setOperatingName(item.getDictValue());
                periodVO.setPeriodYear(vo.getPeriodYear());
                periodVO.setAreaCode(vo.getAreaCode());
                return periodVO;
            }
            List<OperationPeriod> operationPeriods = finalOperationMap.get(item.getDictKey());
            if (CollectionUtils.isEmpty(operationPeriods)) {
                periodVO.setOperating(item.getDictKey());
                periodVO.setOperatingName(item.getDictValue());
                periodVO.setPeriodYear(vo.getPeriodYear());
                periodVO.setAreaCode(vo.getAreaCode());
                return periodVO;
            }
            OperationPeriod operationPeriod = operationPeriods.get(0);
            BeanUtils.copyProperties(operationPeriod, periodVO);
            return periodVO;
        }).collect(Collectors.toList());

        List<OperationPeriodVO> voList = new ArrayList<>();

        for (OperationPeriodVO operationPeriod : list) {
            OperationPeriodVO operationPeriodVO =
                    Convert.convert(OperationPeriodVO.class, operationPeriod);
            if(operationPeriodVO.getOrgId()!=null) {
                setDict(operationPeriodVO);
            }
            voList.add(operationPeriodVO);
        }

        dictHelper.valueToName(voList, Arrays.asList(OperatingPeriodDictEnum.values()));
        return PagerUtil.parsePagerVo(voList, pageInfo);
    }


    private void setDict(OperationPeriodVO vo) {
        if (StringUtils.isNotBlank(vo.getOrgId())) {
            DictQueryVO queryVO=new DictQueryVO();
            queryVO.setOrgId(vo.getOrgId());
            vo.setOrgName(dictIntegration.getOrgNameById(queryVO));
        }
        if (vo.getAppId()!=null) {
            DictQueryVO queryVO=new DictQueryVO();
            queryVO.setAppId(vo.getAppId());
            vo.setAppName(dictIntegration.getAppNameById(queryVO));
        }
    }
}
